package com.lagou.config;


import com.lagou.annotation.MyAutowired;
import com.lagou.annotation.MyTransactional;
import com.lagou.factory.ProxyFactory;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;


public class CustomApplicationContext {
    //包名
//    private String packageName;
//    private ConcurrentHashMap<String, Object> beans = new ConcurrentHashMap<>();
//
//    public CustomApplicationContext(String packageName) {
//        this.packageName = packageName;
//        initBeans();
//    }
//
//    private void initBeans() {
//        List<Class> classList = getClasses(packageName);
//        findClassIsAddedCostomAnnotation(classList);
//    }
//
//    private List<Class> getClasses(String packageName) {
//        List<Class> classList = new ArrayList<>();
//        String packageDirName = packageName.replace(".", "/");
//        Enumeration<URL> dirs;
//        try {
//            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
//            while (dirs.hasMoreElements()) {
//                URL url = dirs.nextElement();
//                String protocol = url.getProtocol();
//                if (protocol.equals("file")) {
//                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
//                    findAndAddClassesInPackageByFile(packageName, filePath, classList);
//                }
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return classList;
//    }
//
//    private void findAndAddClassesInPackageByFile(String packageName, String filePath, List<Class> classList) {
//        File dir = new File(filePath);
//        //选出文件夹下面所有的文件
//        File[] files = dir.listFiles(new FileFilter() {
//            public boolean accept(File file) {
//                return (file.isDirectory() || file.getName().endsWith(".class"));
//            }
//        });
//        for (File file : files) {
//            if (file.isDirectory()) {
//                findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), classList);
//            } else {
//                String className = file.getName().substring(0, file.getName().length() - 6);
//                try {
//                    classList.add(Class.forName(packageName + "." + className));
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }
//
//    private void findClassIsAddedCostomAnnotation(List<Class> classList) {
//        try{
//            for (Class aClass : classList) {
//                classToObjectIntoBeans(aClass, classList);
//            }
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//    }
//
//    private void classToObjectIntoBeans(Class aClass, List<Class> classList) {
//        Object obj = null;
//
//        try{
//            if(aClass.isInterface()){
//                for(Class implClass : classList) {
//                    if (implClass.isInterface()) {
//                        continue;
//                    }
//                    Class fieldClassCopy = implClass.getClassLoader().loadClass(aClass.getName());
//                    if (fieldClassCopy.isAssignableFrom(implClass)) {
//                        Constructor[] constructors = implClass.getConstructors();
//                        for(Constructor constructor : constructors){
//                            int parameterCount = constructor.getParameterCount();
//                            if(parameterCount==0){
//                                obj = constructor.newInstance();
//                            }
//                        }
//                        break;
//                    }
//                }
//            } else {
//                Constructor[] constructors = aClass.getConstructors();
//                for(Constructor constructor : constructors){
//                    int parameterCount = constructor.getParameterCount();
//                    if(parameterCount==0){
//                        obj = constructor.newInstance();
//                    }
//                }
//            }
//            if (obj != null) {
//                beans.put(aClass.getSimpleName(), obj);
//            }
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//    }
//
//    public Object getBean(String beanName,CustomApplicationContext customApplicationContext) {
//        Object beanObject = beans.get(beanName);
//        try{
//            referenceBindObject(beanObject);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//
//        Class aClass = beanObject.getClass();
//        Annotation annotation = aClass.getAnnotation(MyTransactional.class);
//        if (annotation != null) {
//            ProxyFactory proxyFactory = (ProxyFactory) customApplicationContext.getBean("ProxyFactory", customApplicationContext);
//            beanObject = proxyFactory.getJdkProxy(beanObject);
//        }
//        return beanObject;
//    }
//
//    private Object referenceBindObject(Object beanObject) {
//        Class beanClass = beanObject.getClass();
//        Field[] declaredFields = beanClass.getDeclaredFields();
//        try {
//            for (Field field : declaredFields) {
//                if (!field.isAccessible()) {
//                    field.setAccessible(true);
//                }
//                MyAutowired filedAnnotation = field.getAnnotation(MyAutowired.class);
//                if (filedAnnotation == null) {
//                    System.out.println(beanClass.getName() + "类中的" + field.getName() + "字段,该字段上没有加注解");
//                    break;
//                }
//                Class fieldClass = field.getType();
//                String classSimpleName = fieldClass.getSimpleName();
//                Object fieldObject = beans.get(classSimpleName);
//                Object object = referenceBindObject(fieldObject);
//                field.set(beanObject, object);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return beanObject;
//    }

}